From 92d81c3c284e90da3169e79b5e8ab91e17403961 Mon Sep 17 00:00:00 2001 From: "kaf24@freefall.cl.cam.ac.uk" Date: Sat, 13 Nov 2004 16:10:28 +0000 Subject: [PATCH] bitkeeper revision 1.1159.170.18 (419631f46LScNrXRGEL-VrxeFQPSBA) Clean up keyhandler interface. Now register a new keyhandler with register_keyhandler() or register_irq_keyhandler(). --- xen/arch/x86/pdb-stub.c | 2 +- xen/common/ac_timer.c | 2 +- xen/common/keyhandler.c | 86 +++++++++++++++++++++++------------- xen/include/xen/keyhandler.h | 43 +++++++++++++----- 4 files changed, 88 insertions(+), 45 deletions(-) diff --git a/xen/arch/x86/pdb-stub.c b/xen/arch/x86/pdb-stub.c index de1149e7ff..a6133b78ae 100644 --- a/xen/arch/x86/pdb-stub.c +++ b/xen/arch/x86/pdb-stub.c @@ -1244,7 +1244,7 @@ void initialize_pdb() /* Acknowledge any spurious GDB packets. */ pdb_put_char('+'); - add_key_handler('D', pdb_key_pressed, "enter pervasive debugger"); + register_keyhandler('D', pdb_key_pressed, "enter pervasive debugger"); pdb_initialized = 1; } diff --git a/xen/common/ac_timer.c b/xen/common/ac_timer.c index ddef6d33c3..a33498090b 100644 --- a/xen/common/ac_timer.c +++ b/xen/common/ac_timer.c @@ -286,5 +286,5 @@ void __init ac_timer_init(void) spin_lock_init(&ac_timers[i].lock); } - add_key_handler('a', dump_timerq, "dump ac_timer queues"); + register_keyhandler('a', dump_timerq, "dump ac_timer queues"); } diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index 045f861880..d6eb85250b 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -1,3 +1,6 @@ +/****************************************************************************** + * keyhandler.c + */ #include #include @@ -10,49 +13,61 @@ #define KEY_MAX 256 #define STR_MAX 64 -static struct { - key_handler *handler; - int flags; +static struct { + union { + keyhandler_t *handler; + irq_keyhandler_t *irq_handler; + } u; + unsigned int flags; char desc[STR_MAX]; } key_table[KEY_MAX]; -#define KEYHANDLER_NO_DEFER 0x1 +#define KEYHANDLER_IRQ_CALLBACK 0x1 static unsigned char keypress_key; void keypress_softirq(void) { - key_handler *h; + keyhandler_t *h; unsigned char key = keypress_key; - if ( (h = key_table[key].handler) != NULL ) + if ( (h = key_table[key].u.handler) != NULL ) (*h)(key); } void handle_keypress(unsigned char key, struct xen_regs *regs) { - key_handler *h; + irq_keyhandler_t *h; - keypress_key = key; - if ( (key_table[key].flags & KEYHANDLER_NO_DEFER) && - ((h = key_table[key].handler) != NULL) ) - ((void (*)(unsigned char, struct xen_regs *))*h)(key, regs); + if ( key_table[key].flags & KEYHANDLER_IRQ_CALLBACK ) + { + if ( (h = key_table[key].u.irq_handler) != NULL ) + (*h)(key, regs); + } else + { + keypress_key = key; raise_softirq(KEYPRESS_SOFTIRQ); + } } -void add_key_handler(unsigned char key, key_handler *handler, char *desc) +void register_keyhandler( + unsigned char key, keyhandler_t *handler, char *desc) { - key_table[key].handler = handler; - key_table[key].flags = 0; + ASSERT(key_table[key].u.handler == NULL); + key_table[key].u.handler = handler; + key_table[key].flags = 0; strncpy(key_table[key].desc, desc, STR_MAX); key_table[key].desc[STR_MAX-1] = '\0'; } -void add_key_handler_no_defer(unsigned char key, key_handler *handler, - char *desc) +void register_irq_keyhandler( + unsigned char key, irq_keyhandler_t *handler, char *desc) { - add_key_handler(key, handler, desc); - key_table[key].flags |= KEYHANDLER_NO_DEFER; + ASSERT(key_table[key].u.irq_handler == NULL); + key_table[key].u.irq_handler = handler; + key_table[key].flags = KEYHANDLER_IRQ_CALLBACK; + strncpy(key_table[key].desc, desc, STR_MAX); + key_table[key].desc[STR_MAX-1] = '\0'; } static void show_handlers(unsigned char key) @@ -60,16 +75,15 @@ static void show_handlers(unsigned char key) int i; printk("'%c' pressed -> showing installed handlers\n", key); for ( i = 0; i < KEY_MAX; i++ ) - if ( key_table[i].handler != NULL ) + if ( key_table[i].u.handler != NULL ) printk(" key '%c' (ascii '%02x') => %s\n", (i<33 || i>126)?(' '):(i),i, key_table[i].desc); } -static void dump_registers(unsigned char key) +static void dump_registers(unsigned char key, struct xen_regs *regs) { - struct xen_regs *regs = (struct xen_regs *)get_execution_context(); extern void show_registers(struct xen_regs *regs); printk("'%c' pressed -> dumping registers\n", key); show_registers(regs); @@ -143,20 +157,30 @@ void initialize_keytable(void) { open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq); - add_key_handler('d', dump_registers, "dump registers"); - add_key_handler('h', show_handlers, "show this message"); - add_key_handler('l', print_sched_histo, "print sched latency histogram"); - add_key_handler('L', reset_sched_histo, "reset sched latency histogram"); - add_key_handler('q', do_task_queues, "dump task queues + guest state"); - add_key_handler('r', dump_runq, "dump run queues"); - add_key_handler('R', halt_machine, "reboot machine"); + register_irq_keyhandler( + 'd', dump_registers, "dump registers"); + register_keyhandler( + 'h', show_handlers, "show this message"); + register_keyhandler( + 'l', print_sched_histo, "print sched latency histogram"); + register_keyhandler( + 'L', reset_sched_histo, "reset sched latency histogram"); + register_keyhandler( + 'q', do_task_queues, "dump task queues + guest state"); + register_keyhandler( + 'r', dump_runq, "dump run queues"); + register_keyhandler( + 'R', halt_machine, "reboot machine"); #ifndef NDEBUG - add_key_handler('o', audit_domains_key, "audit domains >0 EXPERIMENTAL"); + register_keyhandler( + 'o', audit_domains_key, "audit domains >0 EXPERIMENTAL"); #endif #ifdef PERF_COUNTERS - add_key_handler('p', perfc_printall, "print performance counters"); - add_key_handler('P', perfc_reset, "reset performance counters"); + register_keyhandler( + 'p', perfc_printall, "print performance counters"); + register_keyhandler( + 'P', perfc_reset, "reset performance counters"); #endif } diff --git a/xen/include/xen/keyhandler.h b/xen/include/xen/keyhandler.h index 09e2f234ad..e3d49c9086 100644 --- a/xen/include/xen/keyhandler.h +++ b/xen/include/xen/keyhandler.h @@ -1,16 +1,35 @@ -/* -** We keep an array of 'handlers' for each key code between 0 and 255; -** this is intended to allow very simple debugging routines (toggle -** debug flag, dump registers, reboot, etc) to be hooked in in a slightly -** nicer fashion than just editing the serial/keyboard drivers. -*/ -struct xen_regs; +/****************************************************************************** + * keyhandler.h + * + * We keep an array of 'handlers' for each key code between 0 and 255; + * this is intended to allow very simple debugging routines (toggle + * debug flag, dump registers, reboot, etc) to be hooked in in a slightly + * nicer fashion than just editing the serial/keyboard drivers. + */ -typedef void key_handler(unsigned char key); +#ifndef __XEN_KEYHANDLER_H__ +#define __XEN_KEYHANDLER_H__ -extern void add_key_handler(unsigned char key, - key_handler *handler, char *desc); -extern void add_key_handler_no_defer(unsigned char key, - key_handler *handler, char *desc); +#include +/* + * Register a callback function for key @key. The callback occurs in + * softirq context with no locks held and interrupts enabled. + */ +typedef void keyhandler_t(unsigned char key); +extern void register_keyhandler( + unsigned char key, keyhandler_t *handler, char *desc); + +/* + * Register an IRQ callback function for key @key. The callback occurs + * synchronously in hard-IRQ context with interrupts disabled. The @regs + * callback parameter points at the interrupted register context. + */ +typedef void irq_keyhandler_t(unsigned char key, struct xen_regs *regs); +extern void register_irq_keyhandler( + unsigned char key, irq_keyhandler_t *handler, char *desc); + +/* Inject a keypress into the key-handling subsystem. */ extern void handle_keypress(unsigned char key, struct xen_regs *regs); + +#endif /* __XEN_KEYHANDLER_H__ */ -- 2.30.2